<?php

/*
 * Specific ZenityException class
 */
class ZenityException extends Exception
{

}

/*
 * Zenity allow to make zenity dialog box (see man zenity under GNU/Linux)
 * display GTK+ dialogs
 * PHP command line scripts only
 * require zenity to be installed
 */
class Zenity
{
	protected $type;
	protected $text;
	protected $value;
	protected $step;
	protected $hideValue;
	protected $result;
	protected $pulsate;
	protected $title;
	protected $windowIcon;
	protected $width;
	protected $height;
	
	// Make a new instance of Zenity with specified type and text
	public function __construct($type=null, $text=null)
	{
		if($type != null) $this->setType($type);
		if($text != null) $this->setText($text);
	}
	
	// Set the dialog type (see the list below)
	public function setType($type)
	{
		$validType = array('info','error','scale','progress','question');
		if(in_array($type, $validType))
		{
			$this->type = $type;
		}
		else 
		{
			throw new ZenityException('Not a valid type');
		}
	}
	
	// Internal function to escape quote for shell
	private function quoteEscape($str)
	{
		return str_replace('"', '\"', $str);
	}
	
	// Set the main text for the dialog
	public function setText($text)
	{
		$this->text = $this->quoteEscape($text);
	}
	
	// Set the title of the dialog window
	public function setTitle($t)
	{
		$this->title = $this->quoteEscape($t);
	}
	
	// Set the window icon
	public function setWindowIcon($icon)
	{
		$this->windowIcon = $icon;
	}
	
	// Set the with of the window
	public function setWidth($width)
	{
		$this->width = (int)$width;
	}
	
	// Set the height of the window
	public function setHeight($height)
	{
		$this->height = (int)$height;
	}
	
	// Set the "value" value for specific dialog type (see nam zenity)
	public function setValue($value)
	{
		$value = (int)$value;
		if($value > 100 || $value < 0)
		{
			throw new ZenityException('Value out of range [0-100]');
		}
		$this->value = $value;
	}
	
	// Set the "step" value for specific dialog type (see man zenity)
	public function setStep($step)
	{
		$step = (int)$step;
		if($step > 100 || $step < 0)
		{
			throw new ZenityException('Step out of range [0-100]');
		}
		$this->step = $step;
	}
	
	// Set the "hideValue" value for specific dialog type (see man zenity)
	public function setHideValue($b)
	{
		$this->hideValue = (bool)$b;
	}
	
	// Set the "pulsate" value for specific dialog type (see man zenity)
	public function setPulsate($p)
	{
		$this->pulsate = (bool)$p;
	}
	
	// Get the dialog result
	public function getResult()
	{
		if(isset($this->result))
		{
			return $this->result;
		}
		return null;
	}
	
	// Get the generated command line
	public function __toString()
	{
		return $this->show(true);
	}
	
	
	// Show the dialog
	public function show($string=false)
	{
		$cmd = 'zenity ';
		
		if(empty($this->type))
		{
			throw new ZenityException('Type is not defined');
		}
		
		$cmd.= ' --'.$this->type;
		
		if(!empty($this->text))       $cmd.= ' --text="'       .$this->text.'"';
		if(!empty($this->title))      $cmd.= ' --title="'      .$this->title.'"';
		if(!empty($this->windowIcon)) $cmd.= ' --window-icon="'.$this->windowIcon.'"';
		if(!empty($this->width))      $cmd.= ' --width='       .$this->width;
		if(!empty($this->height))     $cmd.= ' --height='      .$this->height;
		
		switch($this->type)
		{
			case "scale":
				if(!empty($this->value)) $cmd.= ' --value='.$this->value;
				if(!empty($this->step))  $cmd.= ' --step='.$this->step;
				if($this->hideValue)     $cmd.= ' --hide-value';
				break;
				
			case "pulsate":
				if($this->pulsate) $cmd.= ' --pulsate';
				break;
				
			default:
				break;
		}
		
		if($string) 
		{
			return $cmd;
		}
		
		$code = 0;
		$null = array();
		
		$this->result = exec($cmd, $null, $code);
		
		// Because question type return an exit code and does not write on the output
		if(empty($this->result))
		{
			$this->result = !(bool)$code;
		}
		
		return $this->result;
	}
	
	// Specific errorDialog function to setup one line error message for debugging
	public static function errorDialog($message, $code=0)
	{
		echo 'ERROR: '.$message."\n";
		$zenity = new Zenity('error', $message);
		$zenity->show();
		
		if($code > 0)
		{
			exit($code);
		}
		
		return;
	}
}


